Skip to content

Optimize unit_return_expecting_ord#14905

Merged
samueltardieu merged 1 commit intorust-lang:masterfrom
blyxyas:minimize-interning
May 28, 2025
Merged

Optimize unit_return_expecting_ord#14905
samueltardieu merged 1 commit intorust-lang:masterfrom
blyxyas:minimize-interning

Conversation

@blyxyas
Copy link
Copy Markdown
Member

@blyxyas blyxyas commented May 27, 2025

This lint was previously written very clumsily, not short-circuiting and doing a lot of unnecessary work.

Now it makes sure to do the cheaper functions earlier and in general, is just smarter.
(I specifically focused on minimizing binder instantiation

Sadly, I'm not finding any relevant result in a benchmark. Still with the LLVM coverage instruments, the expensive bits are called lots of less times (The binder instantiation that I care about is reduced from 95k to 10k throughout our test suite).

changelog:[unit_return_expecting_ord]: Optimize the lint

@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 27, 2025

r? @samueltardieu

rustbot has assigned @samueltardieu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label May 27, 2025
Copy link
Copy Markdown
Member

@samueltardieu samueltardieu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, but you can use interned symbols instead of allocating strings, that can only help (if a little bit) with performances.

fn_mut_trait: DefId,
ord_trait: Option<DefId>,
partial_ord_trait: Option<DefId>,
) -> Vec<(usize, String)> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
) -> Vec<(usize, String)> {
) -> Vec<(usize, Symbol)> {

.any(|ord| Some(ord.self_ty()) == return_ty_pred.term.as_type())
{
args_to_check.push((i, "Ord".to_string()));
args_to_check.push((i, String::from("Ord")));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
args_to_check.push((i, String::from("Ord")));
args_to_check.push((i, sym::Ord));

.any(|pord| pord.self_ty() == return_ty_pred.term.expect_type())
{
args_to_check.push((i, "PartialOrd".to_string()));
args_to_check.push((i, String::from("PartialOrd")));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
args_to_check.push((i, String::from("PartialOrd")));
args_to_check.push((i, sym::PartialOrd));

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it initially and reverted it with some mental gymnastics. I'll re-revert it.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels May 28, 2025
@blyxyas blyxyas force-pushed the minimize-interning branch from 7d0b957 to 2635ced Compare May 28, 2025 15:40
Copy link
Copy Markdown
Member

@samueltardieu samueltardieu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except for the two nits (no need to call .as_str(), and you can inline the trait_name in format string), this LGTM. If you just fix those two places feel free to r=me.

Comment on lines +189 to +192
format!(
"this closure returns \
the unit type which also implements {}",
trait_name.as_str()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
format!(
"this closure returns \
the unit type which also implements {}",
trait_name.as_str()
format!(
"this closure returns \
the unit type which also implements {trait_name}"

Comment on lines +201 to +203
format!(
"this closure returns \
the unit type which also implements {}",
trait_name.as_str()
),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
format!(
"this closure returns \
the unit type which also implements {}",
trait_name.as_str()
),
format!(
"this closure returns \
the unit type which also implements {trait_name}"
),

This lint was previously written very clumsily, not
shortcircuiting and doing a lot of unnecessary work.

Now it makes sure to do the cheaper functions earlier
and in general, just be smarter.
(I specifically focused on minimizing binder instantiation)

Also, avoid allocating unnecessarily
@blyxyas blyxyas force-pushed the minimize-interning branch from 2635ced to 7e590de Compare May 28, 2025 16:00
@blyxyas
Copy link
Copy Markdown
Member Author

blyxyas commented May 28, 2025

feel free to r=me

Sadly we don't have bors anymore, so PRs can't be merged in behalf of another person 😢

@samueltardieu
Copy link
Copy Markdown
Member

I know, this is an inherited way of saying "feel free to press the merge button on my behalf as I take responsibility for it". But since I'm here I'll do it!

@samueltardieu samueltardieu added this pull request to the merge queue May 28, 2025
Merged via the queue into rust-lang:master with commit b90880d May 28, 2025
11 checks passed
declare_lint_pass!(UnitReturnExpectingOrd => [UNIT_RETURN_EXPECTING_ORD]);

fn get_trait_predicates_for_trait_id<'tcx>(
// For each
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment unfinished?

{
preds.push(trait_pred);
.instantiate_bound_regions_with_erased(pred.kind().rebind(poly_trait_pred));
for (i, tid) in trait_ids.iter().enumerate() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The slice/array approach is a bit hard to understand, you have to look at the callsite to understand it. I see you want to get the operations within the instantiate_bound_regions_with_erased call. I think you could do that by passing in three separate arguments and handling them in sequence here, instead of using a for loop? I think that would be easier to read.

@blyxyas blyxyas added the G-performance-project Goal: For issues and PRs related to the Clippy Performance Project label Jun 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

G-performance-project Goal: For issues and PRs related to the Clippy Performance Project S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants